package com.vichat.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.constant.GlobalConstant;
import com.vichat.common.constant.I18nConstant;
import com.vichat.common.enums.RecordType;
import com.vichat.common.exception.ViChatException;
import com.vichat.common.util.DateUtil;
import com.vichat.common.util.I18NUtil;
import com.vichat.common.util.Md5Util;
import com.vichat.common.util.NumberUtils;
import com.vichat.common.vo.PageFilter;
import com.vichat.core.dao.BaseDaoI;
import com.vichat.user.entity.*;
import com.vichat.user.service.IUserAgentService;
import com.vichat.user.service.IUserService;
import com.vichat.user.util.CheckUtils;
import com.vichat.user.vo.AgentUseVO;
import com.vichat.user.vo.AgentUserOnlineVO;
import com.vichat.user.vo.UserCompanyVO;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.type.StringType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.URLDecoder;
import java.util.*;

/**
 * Created by wangluyin on 16/9/17.
 */

@Service("userAgentServiceImpl")
public class UserAgentServiceImpl implements IUserAgentService {
    protected static final Logger logger = LoggerFactory.getLogger(UserAgentServiceImpl.class);
    @Autowired
    private BaseDaoI<UserParty> partyDao;
    @Autowired
    private BaseDaoI<UserPartyCompany> partyCompanyDao;
    @Autowired
    private BaseDaoI<UserBasic> userDao;
    @Autowired
    private IUserService userService;
    @Autowired
    private BaseDaoI<SysAgentBusiRecord> sysAgentBusiRecordDao;
    @Autowired
    private BaseDaoI<UserSecRoleRel> userSecRoleRelDao;
    @Autowired
    private BaseDaoI<UserPartyCompany> userPartyCompanyDao;
    @Autowired
    private BaseDaoI<UserOrg> orgDao;
    @Autowired
    private BaseDaoI<AgentUser> agentUserDao;
    @Autowired
    private BaseDaoI<AgentCompany> agentCompanyDao;
    //    @Autowired
//    private BaseDaoI<RechargeRecord> rechargeRecordDao;
    @Autowired
    private BaseDaoI<AgentUserSecRoleRel> agentUserSecRoleRelDao;
    @Autowired
    private BaseDaoI<SnResource> snResourceDao;
    @Autowired
    private BaseDaoI<CcsUser> ccsUserInfoDao;
    @Autowired
    private BaseDaoI<RechargeRecord> rechargeRecordDao;

    private void updateUserOrgVersion(long orgId) {
        String hql = "update userdb.user_org set version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where org_id = " + orgId;
        orgDao.executeSql(hql);
    }

    public void saveUserPartyCompany(UserPartyCompany company) {
        UserPartyCompany companyFDB = partyCompanyDao.get("from UserPartyCompany where state = 1 and partyId = " + company.getPartyId());
        companyFDB.setAuthNumber(company.getAuthNumber());
//        companyFDB.setFreeType(company.getFreeType());
        companyFDB.setCompanyAddress(company.getCompanyAddress());
        companyFDB.setCompanyCode(company.getCompanyCode());
        companyFDB.setUserName(company.getUserName());
        companyFDB.setCompanyName(company.getCompanyName());
        companyFDB.setTel(company.getTel());
        companyFDB.setFunction(company.getFunction());
        partyCompanyDao.save(companyFDB);
        RedisHelper.setPartyCompany(companyFDB.getPartyId(), JSONObject.toJSONString(companyFDB));
    }


    public UserBasic getPartyUserByPartyId(long partyId, long userType) {
        String hql = "from UserBasic where state = 1 and partyId = :partyId and userType = :userType";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        params.put("userType", userType);
        List<UserBasic> list = userDao.find(hql, params);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 增加子账号
     *
     * @param user
     * @return
     */
    @Override
    public UserBasic saveUserBasicAgent(UserBasic user, AgentUser sessionUser) throws ViChatException {
        if (NumberUtils.isNotNullOrZero(user.getUid())) {
            UserBasic userFDB = userService.queryUserBasicByUid(user.getUid());
            if (userFDB == null) {
                throw new RuntimeException("系统异常，未找到该员工信息，请联系后台技术人员");
            } else {
                if (userFDB.getUserType() != GlobalConstant.USER_TYPE_1 && user.getUserType() != GlobalConstant.USER_TYPE_1) {
                    userFDB.setUserType(user.getUserType());
                }
                changeUserTypeRole(user);
                userFDB.setUserName(user.getUserName());
                userFDB.setSex(user.getSex());
                userFDB.setPhone(user.getPhone());
                userDao.update(userFDB);
                RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));

            }
        } else {
            user.setExpiredDate(DateUtil.getTodayTime("yyyy-MM-dd"));
            if (StringUtils.isBlank(user.getPassword())) {
                user.setPassword("111111");
            }

            this.checkIsAccountExist(user);
            if (StringUtils.isNotBlank(user.getIccid())) {
                user.setTerminal(user.getIccid());
            }
            if (StringUtils.isNotBlank(user.getImei())) {
                user.setTerminal(user.getImei());
            }

            // 用户密码加密处理
            encryptUserBasic(user);
            UserOrg userOrg = null;
            if (NumberUtils.isNotNullOrZero(user.getOrgId())) {
                userOrg = userService.queryUserOrgByOrgId(user.getPartyId(), user.getOrgId());
            } else {
                userOrg = userService.getRootOrgByPartyId(user.getPartyId());
            }
            if (userOrg == null) {
                String errorMsg = I18NUtil.getMessage("error_orgNotExist", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_orgNotExist, errorMsg);
            }

            //判断sn账号是否可用
            if (user.getUserType() == GlobalConstant.USER_TYPE_3 && GlobalConstant.CHECK_TERMINAL_SN) {
                SnResource snResource = this.queryNotAssignSnResourceBySN(user.getImei(), sessionUser.getAgentId());
                if (snResource == null) {
                    String errorMsg = I18NUtil.getMessage("error_snNotExist", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_snNotExist, errorMsg);
                } else {
                    snResource.setResState(0L);
                    snResource.setAgentId(sessionUser.agentId);
                    snResourceDao.update(snResource);
                }
            }
            //判断sn账号是否可用
            if (user.getUserType() == GlobalConstant.USER_TYPE_4 && GlobalConstant.CHECK_DISPATCHER_SN) {
                SnResource snResource = this.queryNotAssignSnResourceBySN(user.getImei(), sessionUser.getAgentId());
                if (snResource == null) {
                    String errorMsg = I18NUtil.getMessage("error_snNotExist", null, Locale.CHINA);
                    throw new ViChatException(I18nConstant.error_snNotExist, errorMsg);
                } else {
                    snResource.setResState(0L);
                    snResourceDao.update(snResource);
                    snResource.setAgentId(sessionUser.agentId);
                }
            }

            if (user.getUserType() == GlobalConstant.USER_TYPE_4) {
                CheckUtils.checkEffetiveDispatcherUserNumberMax(userService, 1);
            } else if (user.getUserType() == GlobalConstant.USER_TYPE_3) {
                CheckUtils.checkEffetiveTerminalUserNumberMax(userService, 1);
            }


            user.setOrgId(userOrg.getOrgId());
            user.setOrgName(userOrg.getOrgName());
            user.setOrgCode(userOrg.getOrgCode());
            userDao.save(user);

            changeUserTypeRole(user);

            RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(user));
        }
        return user;
    }

    private void changeUserTypeRole(UserBasic userBasic) {
        if (NumberUtils.isNotNullOrZero(userBasic.getUserType())) {
            if (userBasic.getUserType() == GlobalConstant.USER_TYPE_1) {
                userService.saveUserSecRoleRel(userBasic.getUid(), 1L);
            } else if (userBasic.getUserType() == GlobalConstant.USER_TYPE_4) {
                userService.saveUserSecRoleRel(userBasic.getUid(), 3L);
            }
        }
    }

    public Map<String, List<UserBasic>> batchCreateUser(List<UserBasic> users, AgentUser sessionUser) {
        Map<String, List<UserBasic>> rtnMap = new HashMap<String, List<UserBasic>>();
        List<UserBasic> successList = new ArrayList<UserBasic>();
        List<UserBasic> failList = new ArrayList<UserBasic>();
        // 批量导入用户初始密码6个1

        for (UserBasic user : users) {
            user.setUid(null);// 清空uid
            user.setUserType(GlobalConstant.USER_TYPE_3);
            user.setPassword("111111");
            try {
                this.saveUserBasicAgent(user, sessionUser);
                successList.add(user);
            } catch (Exception e) {
                logger.error("batchCreateUser", e);
                e.printStackTrace();
                failList.add(user);
            }
        }
        rtnMap.put("SUCCESS_LIST", successList);
        rtnMap.put("FAIL_LIST", failList);
        return rtnMap;
    }

    public Map<String, List<AgentUser>> batchCreateAgentUser(List<AgentUser> users) {
        Map<String, List<AgentUser>> rtnMap = new HashMap<String, List<AgentUser>>();
        List<AgentUser> successList = new ArrayList<AgentUser>();
        List<AgentUser> failList = new ArrayList<AgentUser>();
        // 批量导入用户初始密码6个1

        for (AgentUser user : users) {
            user.setAgentUid(null);// 清空uid
            user.setUserType(GlobalConstant.USER_TYPE_2);
            user.setPassword("111111");
            try {
                this.saveAgentUser(user);
                successList.add(user);
            } catch (Exception e) {
                logger.error("batchCreateUser", e);
                e.printStackTrace();
                failList.add(user);
            }
        }
        rtnMap.put("SUCCESS_LIST", successList);
        rtnMap.put("FAIL_LIST", failList);
        return rtnMap;
    }

    public Map<String, List<UserBasic>> batchUpdateUser(List<UserBasic> users, AgentUser sessionUser) {
        Map<String, List<UserBasic>> rtnMap = new HashMap<String, List<UserBasic>>();
        List<UserBasic> successList = new ArrayList<UserBasic>();
        List<UserBasic> failList = new ArrayList<UserBasic>();

        for (UserBasic user : users) {
            try {
                this.saveUserBasicAgent(user, sessionUser);
                successList.add(user);
            } catch (Exception e) {
                logger.error("batchUpdateUser", e);
                e.printStackTrace();
                failList.add(user);
            }
        }
        rtnMap.put("SUCCESS_LIST", successList);
        rtnMap.put("FAIL_LIST", failList);
        return rtnMap;
    }

    /**
     * 对UserBasic进行密码加密处理
     *
     * @param user
     */
    protected void encryptUserBasic(UserBasic user) {
        String mim = Md5Util.Md5Encode(user.getPassword(), null);
        mim = Md5Util.Md5Encode(mim, null);
        user.setPassword(mim);
    }


    /**
     * 客服修改密码
     *
     * @param uid
     * @param newPassWord
     */
    public UserBasic ccsChgUserPass(long uid, String newPassWord) {
        UserBasic userFDB = userDao.get(UserBasic.class, uid);
        userFDB.setPassword(newPassWord);
        userDao.save(userFDB);
        // 刷新IM
        RedisHelper.setUser(uid, JSONObject.toJSONString(userFDB));
        return userFDB;
    }


    @Override
    public List<UserPartyCompany> queryUserCompanyCCS(UserPartyCompany company, UserBasic user, PageFilter pf, boolean isPrecision) throws Exception {
        String hql;
        HashMap params = new HashMap();
        if (StringUtils.isNotEmpty(user.getTerminal())) {
            hql = "select distinct a from UserPartyCompany a , UserBasic b where a.state = 1 and b.state = 1 and a.partyId = b.partyId";
            if (StringUtils.isNotEmpty(user.getTerminal())) {
                if (!isPrecision) {
                    hql += " and (b.terminal like :terminal or b.imei like :terminal or b.iccid like :terminal)";
                    params.put("terminal", "%" + URLDecoder.decode(user.getTerminal(), "UTF-8") + "%");
                } else {
                    hql += " and (b.terminal = :terminal or b.imei = :terminal or b.iccid = :terminal)";
                    params.put("terminal", URLDecoder.decode(user.getTerminal(), "UTF-8"));
                }
            }
        } else {
            hql = " from UserPartyCompany a  where a.state = 1 ";
        }
        if (StringUtils.isNotEmpty(company.getCompanyName())) {
            hql += " and a.companyName like :companyName";
            params.put("companyName", "%" + URLDecoder.decode(company.getCompanyName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(company.getPartyId())) {
            hql += " and a.partyId = :partyId";
            params.put("partyId", company.getPartyId());
        }
        if (NumberUtils.isNotNull(company.getFreeType())) {
            hql += " and a.freeType = :freeType";
            params.put("freeType", company.getFreeType());
        }
        if (NumberUtils.isNotNull(company.getAgentId())) {
            hql += " and a.agentId = :agentId";
            params.put("agentId", company.getAgentId());
        }

        return partyCompanyDao.find(hql, params, pf.getPage(), pf.getRows());
    }

    /**
     * 查询组织数量
     *
     * @return
     */
    public Long countUserCompanyCCS(UserPartyCompany company, UserBasic user, boolean isPrecision) throws Exception {
        String hql;
        HashMap params = new HashMap();
        if (StringUtils.isNotEmpty(user.getTerminal()) || StringUtils.isNotEmpty(user.getIccid())) {
            hql = " from UserPartyCompany a , UserBasic b where a.state = 1 and b.state = 1 and a.partyId = b.partyId";
            if (StringUtils.isNotEmpty(user.getTerminal())) {
                if (!isPrecision) {
                    hql += " and (b.terminal like :terminal or b.imei like :terminal or b.iccid like :terminal)";
                    params.put("terminal", "%" + URLDecoder.decode(user.getTerminal(), "UTF-8") + "%");
                } else {
                    hql += " and (b.terminal = :terminal or b.imei = :terminal or b.iccid = :terminal)";
                    params.put("terminal", URLDecoder.decode(user.getTerminal(), "UTF-8"));
                }
            }

        } else {
            hql = " from UserPartyCompany a  where a.state = 1 ";
        }
        if (StringUtils.isNotEmpty(company.getCompanyName())) {
            hql += " and a.companyName like :companyName";
            params.put("companyName", "%" + URLDecoder.decode(company.getCompanyName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(company.getPartyId())) {
            hql += " and a.partyId = :partyId";
            params.put("partyId", company.getPartyId());
        }
        if (NumberUtils.isNotNull(company.getFreeType())) {
            hql += " and a.freeType = :freeType";
            params.put("freeType", company.getFreeType());
        }
        if (NumberUtils.isNotNull(company.getAgentId())) {
            hql += " and a.agentId = :agentId";
            params.put("agentId", company.getAgentId());
        }

        return partyCompanyDao.count("select count(distinct a.partyId) " + hql, params);
    }

    //    /**
//     * 保存操作日志
//     *
//     * @param user
//     * @param type
//     * @param opedUid
//     * @param opedUserName
//     * @param opedInfo
//     * @param remark
//     * @throws Exception
//     */
    public void saveSysAgentBusiRecord(AgentUser user, RecordType type, long opedUid, String opedUserName, String opedInfo, String remark) {
        try {
            SysAgentBusiRecord busiRecord = new SysAgentBusiRecord();
            if (user != null) {
                busiRecord.setAgentUid(user.getAgentUid());
                busiRecord.setAgentUname(user.getUserName());
                busiRecord.setAgentId(user.getAgentId());
            }
            busiRecord.setOpedType(type.getCode());
            busiRecord.setUid(opedUid);
            busiRecord.setUserName(opedUserName);
            busiRecord.setOpedInfo(opedInfo);
            busiRecord.setRemark(remark);
            sysAgentBusiRecordDao.save(busiRecord);
        } catch (Exception e) {
            logger.error("保存操作日志失败");
        }
    }

    public UserBasic getUserBasicByTerminal(String terminal) {
        String hql = "from UserBasic where state = 1 and terminal = :terminal";
        HashMap params = new HashMap();
        params.put("terminal", terminal);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    /**
     * 判断账号是否已存在（terminal or iccid or imei）
     *
     * @param userBasic
     */
    public void checkIsAccountExist(UserBasic userBasic) throws ViChatException {
        if (StringUtils.isNotBlank(userBasic.getTerminal())) {
            if (this.isTerminalExist(userBasic.getTerminal())) {
                String errorMsg = I18NUtil.getMessage("error_accountIsExist", null, Locale.CHINA);
                throw new ViChatException(I18nConstant.error_accountIsExist, errorMsg);
            }
        }
        if (StringUtils.isNotBlank(userBasic.getIccid())) {
            if (userService.isIccidExist(userBasic.getIccid())) {
                String errorMsg = I18NUtil.getMessage("error_ICCIDIsExist", null, Locale.CHINA);
                throw new ViChatException(I18nConstant.error_ICCIDIsExist, errorMsg);
            }
        }
        if (StringUtils.isNotBlank(userBasic.getImei())) {
            if (userService.isImeiExist(userBasic.getImei())) {
                String errorMsg = I18NUtil.getMessage("error_IMEIIsExist", null, Locale.CHINA);
                throw new ViChatException(I18nConstant.error_IMEIIsExist, errorMsg);
            }
        }

        if (StringUtils.isBlank(userBasic.getTerminal()) && StringUtils.isBlank(userBasic.getIccid()) && StringUtils.isBlank(userBasic.getImei())) {
            String errorMsg = I18NUtil.getMessage("error_parameter", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_parameter, errorMsg);
        }
    }

    public Boolean isTerminalExist(String terminal) {
        UserBasic userBasicFDB = getUserBasicByTerminal(terminal);
        if (userBasicFDB != null) {
            return true;
        }
        return false;
    }

    public void registerPartyCompany(UserParty party, UserPartyCompany company, UserBasic user) throws ViChatException {
        this.checkIsAccountExist(user);
        //保存企业
        party.setPartyName(company.getCompanyName());
        //企业服务码
        String partyKey = UUID.randomUUID().toString().replaceAll("-", "").replaceAll("[a-zA-Z]", "").substring(0, 8);
        party.setPartyKey(partyKey);
        partyDao.save(party);
        RedisHelper.setParty(party.getPartyId(), JSONObject.toJSONString(party));
        //创建公司
        company.setPartyId(party.getPartyId());
        company.setAccount(user.getTerminal());
        if (StringUtils.isNotBlank(company.getContactName())) {
            company.setUserName(company.getContactName());
        }
        if (company.getFreeType() == null) {
            company.setFreeType(GlobalConstant.FREE_TYPE_1);// 收费，按用户失效期收费
            company.setAuthMonth(0L);
        }
        userPartyCompanyDao.save(company);
        RedisHelper.setPartyCompany(party.getPartyId(), JSONObject.toJSONString(company));
        //创建默认组织
        UserOrg org = new UserOrg();
        org.setOrgName(company.getCompanyName());
        org.setPartyId(party.getPartyId());
        String orgCode = this.getOrgCode(org);
        org.setOrgCode(orgCode);
        orgDao.save(org);
        this.updateUserOrgVersion(org.getOrgId());
        RedisHelper.setOrg(org.getOrgId(), JSONObject.toJSONString(org));
        encryptAccount(user);

        //保存登陆账号
        user.setUserName(company.getCompanyName());
        user.setUserType(GlobalConstant.USER_USER_TYPE_OWNER_1);
        user.setPartyId(party.getPartyId());
        user.setOrgId(org.getOrgId());
        user.setOrgCode(orgCode);
        user.setExpiredDate(DateUtil.getTodayTime("yyyy-MM-dd"));
        userDao.save(user);
        userService.updateUserBasicVersion(user.getUid());

        //增加对应关系
        UserSecRoleRel roleRole = new UserSecRoleRel();
        roleRole.setRoid(1L);
        roleRole.setUid(user.getUid());
        roleRole.setState(1L);
        roleRole.setUpdateTime(new Date());
        roleRole.setCreateTime(new Date());
        userSecRoleRelDao.save(roleRole);

        RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(user));
    }

    @Override
    public AgentUser getAgentUserByUid(long uid) {
        String jsonStr = RedisHelper.getAgentUser(uid);
        AgentUser userFDB = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            userFDB = JSONObject.parseObject(jsonStr, AgentUser.class);
        } else {
            userFDB = agentUserDao.get(AgentUser.class, uid);
            if (userFDB != null) {
                RedisHelper.setAgentUser(userFDB.getAgentUid(), JSONObject.toJSONString(userFDB));
            }
        }
        return userFDB;

    }

    @Override
    public AgentUser getAgentUserByAccount(String account) {
        String hql = "from AgentUser where  account = :account";
        HashMap params = new HashMap();
        params.put("account", account);
        List<AgentUser> users = agentUserDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    @Override
    public AgentUser getAgentUserByAccountToLogin(String account) {
        String hql = "from AgentUser where  account = :account and state = 1";
        HashMap params = new HashMap();
        params.put("account", account);
        List<AgentUser> users = agentUserDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    public AgentCompany getAgentCompanyByAgentId(long agentId) {
        return agentCompanyDao.get("from AgentCompany where state = 1 and agentId = " + agentId);
    }

    @Override
    public void updateExpiredDate(AgentUser sessionUser, UserBasic userFDB, Integer monthNumber) throws ViChatException {
        AgentCompany agentCompany = this.getAgentCompanyByAgentId(sessionUser.getAgentId());
        UserPartyCompany company = userService.getUserPartyCompanyByPartyId(userFDB.getPartyId());
        if (agentCompany != null && company != null) {

            rechargeRecordUserIn(sessionUser, agentCompany, userFDB, company, monthNumber);

            rechargeRecordUserOut(sessionUser, agentCompany, userFDB, company, monthNumber);

            //更新所剩额度
            agentCompany.setAuthMonth(agentCompany.getAuthMonth() - monthNumber);
            agentCompanyDao.update(agentCompany);
            RedisHelper.setAgentCompany(agentCompany.getAgentId(), JSONObject.toJSONString(agentCompany));
        } else {
            String errorMsg = I18NUtil.getMessage("error_agentCompanyNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_agentCompanyNotExist, errorMsg);
        }
    }

    private void rechargeRecordUserIn(AgentUser sessionUser, AgentCompany agentCompany, UserBasic userFDB, UserPartyCompany company, Integer monthNumber) {
        Date oldExpiredDate = userFDB.getExpiredDate();
        Date newExpiredDate = DateUtil.addMonth(userFDB.getExpiredDate(), monthNumber);


        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj1PartyId(company.getPartyId());
        rechargeRecord.setObj1PartyName(company.getCompanyName());
        rechargeRecord.setObj1Type(3L);
        rechargeRecord.setObj1Uid(userFDB.getUid());
        rechargeRecord.setObj1Uname(userFDB.getUserName());
        rechargeRecord.setObj2PartyId(agentCompany.getAgentId());
        rechargeRecord.setObj2PartyName(agentCompany.getCompanyName());
        rechargeRecord.setObj2Type(2L);
        rechargeRecord.setObj2Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj2Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(1L);
        rechargeRecord.setChgBefore(DateUtil.getFormattedDate(oldExpiredDate));
        rechargeRecord.setChgAfter(DateUtil.getFormattedDate(newExpiredDate));
        rechargeRecord.setChgValue((long) monthNumber);
        rechargeRecord.setChgType(1L);
        rechargeRecord.setCreateTime(new Date());
        rechargeRecordDao.save(rechargeRecord);

        userFDB.setExpiredDate(newExpiredDate);
        userDao.update(userFDB);
        RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));
    }

    private void rechargeRecordUserOut(AgentUser sessionUser, AgentCompany agentCompany, UserBasic userFDB, UserPartyCompany company, Integer monthNumber) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj2PartyId(company.getPartyId());
        rechargeRecord.setObj2PartyName(company.getCompanyName());
        rechargeRecord.setObj2Type(3L);
        rechargeRecord.setObj2Uid(userFDB.getUid());
        rechargeRecord.setObj2Uname(userFDB.getUserName());
        rechargeRecord.setObj1PartyId(agentCompany.getAgentId());
        rechargeRecord.setObj1PartyName(agentCompany.getCompanyName());
        rechargeRecord.setObj1Type(2L);
        rechargeRecord.setObj1Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(1L);
        rechargeRecord.setChgBefore(String.valueOf(agentCompany.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(agentCompany.getAuthMonth() - monthNumber));
        rechargeRecord.setChgValue((long) (0 - monthNumber));
        rechargeRecord.setChgType(2L);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    /**
     * 对账号进行密码加密处理
     *
     * @param account
     */
    private void encryptAccount(UserBasic account) {
        String mim = Md5Util.Md5Encode(account.getPassword(), null);
        mim = Md5Util.Md5Encode(mim, null);
        account.setPassword(mim);
    }

    /**
     * 获取组织编号
     *
     * @param org
     * @return
     */
    private String getOrgCode(UserOrg org) {
        StringBuilder sql = new StringBuilder();
        if (NumberUtils.isNullOrZero(org.getParentId())) {
            sql.append("select LPAD(max(org_code+1),6,0) ID from user_org where parent_id=0");
        } else {
            sql.append("select concat(MIN(t.org_code),substr(concat('00',substr(MAX(t.org_code),length(MIN(t.org_code))+1,3)+1),length(concat('00',substr(MAX(t.org_code),length(MIN(t.org_code))+1,3)+1))-2,3)) ID from user_org t where t.org_code like '");
            sql.append(org.getOrgCode()).append("%'");
        }
        String orgCode = (String) orgDao.executeQueryBasic(sql.toString(), "ID", StringType.INSTANCE);
        if (StringUtils.isBlank(orgCode)) {
            orgCode = "000001";
        }
        return orgCode;
    }

    public List<AgentUser> queryAgentUsers(AgentUser user, PageFilter pf) throws Exception {
        String hql = "from AgentUser where state=1";
        Map<String, Object> params = new HashMap<String, Object>();
        return agentUserDao.find(hql + agentUserWhereHql(user, params), params, pf.getPage(), pf.getRows());
    }

    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String agentUserWhereHql(AgentUser bean, Map<String, Object> params) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getAgentUid())) {
                hql += " and agentUid = :agentUid";
                params.put("agentUid", bean.getAgentUid());
            }

            if (StringUtils.isNotBlank(bean.getUserName())) {
                hql += " and (userName like :userName or  account like :userName )";
                params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
            }

            if (StringUtils.isNotBlank(bean.getAccount())) {
                hql += " and account like :account ";
                params.put("account", "%" + bean.getAccount() + "%");
            }
            if (StringUtils.isNotBlank(bean.getTel())) {
                hql += " and tel like :tel";
                params.put("tel", "%" + bean.getTel() + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getUserType())) {
                hql += " and userType = :userType";
                params.put("userType", bean.getUserType());
            }
            if (NumberUtils.isNotNullOrZero(bean.getAgentId())) {
                hql += " and agentId = :agentId";
                params.put("agentId", bean.getAgentId());
            }
        }
        return hql;
    }

    @Override
    public void registerAgentCompany(AgentUser user, AgentCompany company) throws ViChatException {
        checkIsAgentAccountExist(user.getAccount());
        company.setCreateTime(new Date());
        company.setUpdateTime(new Date());
        company.setAuthMonth(0L);
        company.setAuthNumber(0L);
        company.setAgentCode(this.getAgentCode(company));
        agentCompanyDao.save(company);
        RedisHelper.setAgentCompany(company.getAgentId(), JSONObject.toJSONString(company));

        encryptAccount(user);

        //保存登陆账号
        user.setUserType(GlobalConstant.USER_USER_TYPE_OWNER_1);
        user.setAgentId(company.getAgentId());
        user.setUserName(company.getCompanyName());
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        agentUserDao.save(user);

        //增加对应关系
        AgentUserSecRoleRel roleRole = new AgentUserSecRoleRel();
        roleRole.setRoid(1L);
        roleRole.setAgentUid(user.getAgentUid());
        roleRole.setState(1L);
        roleRole.setUpdateTime(new Date());
        roleRole.setCreateTime(new Date());
        agentUserSecRoleRelDao.save(roleRole);

        RedisHelper.setAgentUser(user.getAgentUid(), JSONObject.toJSONString(user));
    }

    /**
     * 判断账号是否已存在
     *
     * @param account
     */
    public void checkIsAgentAccountExist(String account) throws ViChatException {
        AgentUser agentUser = getAgentUserByAccount(account);
        if (agentUser != null) {
            String errorMsg = I18NUtil.getMessage("UserServiceImpl.checkIsAccountExist.error_AccountIsExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_accountIsExist, errorMsg);
        }
    }

    /**
     * 对账号进行密码加密处理
     *
     * @param account
     */
    private void encryptAccount(AgentUser account) {
        String mim = Md5Util.Md5Encode(account.getPassword(), null);
        mim = Md5Util.Md5Encode(mim, null);
        account.setPassword(mim);
    }

    @Override
    public List<AgentCompany> queryAgentCompany(AgentUser user, AgentCompany company, PageFilter pf) throws Exception {
        String hql;
        HashMap params = new HashMap();
        if (StringUtils.isNotEmpty(user.getAccount())) {
            hql = "select distinct a from AgentCompany a , AgentUser b where a.state = 1 and  a.agentId = b.agentId ";
            if (StringUtils.isNotEmpty(user.getAccount())) {
                hql += " and b.account like :account";
                params.put("account", "%" + URLDecoder.decode(user.getAccount(), "UTF-8") + "%");
            }
        } else {
            hql = " from AgentCompany a  where a.state = 1 ";
        }
        if (StringUtils.isNotEmpty(company.getCompanyName())) {
            hql += " and a.companyName like :companyName";
            params.put("companyName", "%" + URLDecoder.decode(company.getCompanyName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(company.getAgentId())) {
            hql += " and a.agentId = :agentId";
            params.put("agentId", company.getAgentId());
        }
        if (NumberUtils.isNotNullOrZero(company.getParentId())) {
            hql += " and a.parentId = :parentId";
            params.put("parentId", company.getParentId());
        }

        return agentCompanyDao.find(hql, params, pf.getPage(), pf.getRows());
    }

    public long countAgentCompany(AgentUser user, AgentCompany company) throws Exception {
        String hql;
        HashMap params = new HashMap();
        if (StringUtils.isNotEmpty(user.getAccount())) {
            hql = "  AgentCompany a , AgentUser b where a.state = 1 and a.agentId = b.agentId ";
            if (StringUtils.isNotEmpty(user.getAccount())) {
                hql += " and b.account like :account";
                params.put("account", "%" + URLDecoder.decode(user.getAccount(), "UTF-8") + "%");
            }
        } else {
            hql = " AgentCompany a  where a.state = 1 ";
        }
        if (StringUtils.isNotEmpty(company.getCompanyName())) {
            hql += " and a.companyName like :companyName";
            params.put("companyName", "%" + URLDecoder.decode(company.getCompanyName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(company.getAgentId())) {
            hql += " and a.agentId = :agentId";
            params.put("agentId", company.getAgentId());
        }
        if (NumberUtils.isNotNullOrZero(company.getParentId())) {
            hql += " and a.parentId = :parentId";
            params.put("parentId", company.getParentId());
        }
        return agentCompanyDao.count("select count(distinct a.agentId) from " + hql, params);
    }

    public AgentUser getAgentUserByAgentId(long agentId, long userType) {
        String hql = "from AgentUser where agentId = :agentId and userType = :userType";
        HashMap params = new HashMap();
        params.put("agentId", agentId);
        params.put("userType", userType);
        List<AgentUser> list = agentUserDao.find(hql, params);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    public void saveAgentCompany(AgentCompany company) {
        AgentCompany companyFDB = agentCompanyDao.get("from AgentCompany where state = 1 and agentId = " + company.getAgentId());
        if (companyFDB != null) {
            if (StringUtils.isNotBlank(company.getAdminName())) {
                companyFDB.setAdminName(company.getAdminName());
            }
            companyFDB.setAddress(company.getAddress());
            companyFDB.setEmail(company.getEmail());
            companyFDB.setMobile(company.getMobile());
            companyFDB.setUrl(company.getUrl());
            if (StringUtils.isNotBlank(company.getRemark())) {
                companyFDB.setRemark(company.getRemark());
            }
            companyFDB.setUpdateTime(new Date());
            agentCompanyDao.update(companyFDB);
            RedisHelper.setAgentCompany(companyFDB.getAgentId(), JSONObject.toJSONString(companyFDB));
        }
    }

    /**
     * 客服修改代理商密码
     *
     * @param uid
     * @param newPassWord
     */
    public AgentUser ccsChgAgentUserPass(long uid, String newPassWord) {
        AgentUser userFDB = agentUserDao.get(AgentUser.class, uid);
        userFDB.setPassword(newPassWord);
        agentUserDao.save(userFDB);
        // 刷新IM
        RedisHelper.setAgentUser(uid, JSONObject.toJSONString(userFDB));
        return userFDB;
    }

    public Long countAgentUsers(AgentUser user) throws Exception {
        String hql = "select count(*) from AgentUser where state=1 ";
        Map<String, Object> params = new HashMap<String, Object>();
        return agentUserDao.count(hql + agentUserWhereHql(user, params), params);
    }

    /**
     * 保存或者修改用户信息
     *
     * @param user
     * @return
     */
    public AgentUser saveAgentUser(AgentUser user) throws ViChatException {

        if (NumberUtils.isNullOrZero(user.getAgentUid())) {//新增
            if (StringUtils.isBlank(user.getPassword())) {
                user.setPassword("111111");
            }
            checkAgentUserAccountExist(user.getAccount());
            String mim = Md5Util.Md5Encode(Md5Util.Md5Encode(user.getPassword(), null), null);
            user.setPassword(mim);
            user.setUserType(GlobalConstant.USER_TYPE_2);
            agentUserDao.save(user);
            RedisHelper.setAgentUser(user.getAgentUid(), JSONObject.toJSONString(user));
            return user;
        } else {//修改
            AgentUser userFDB = getAgentUserByUid(user.getAgentUid());
            if (userFDB == null) {
//                throw new Exception("uid:" + user.getUid() + " 的用户不存在");
                String errorMsg = I18NUtil.getMessage("RoomApiController.getRooms.error_userNotExist", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_userNotExist, errorMsg);
            }

            //企业级管理员不可修改用户类型，也不可被改成企业级管理员
//            if (userFDB.getUserType() != GlobalConstant.USER_TYPE_1 && user.getUserType() != GlobalConstant.USER_TYPE_1) {
//                userFDB.setUserType(user.getUserType());
//            }

            userFDB.setUserName(user.getUserName());
            userFDB.setTel(user.getTel());
            userFDB.setEmail(user.getEmail());
            userFDB.setSex(user.getSex());
            userFDB.setUpdateTime(new Date());
            agentUserDao.update(userFDB);
            RedisHelper.setAgentUser(userFDB.getAgentUid(), JSONObject.toJSONString(userFDB));
            return userFDB;

        }
    }

    /**
     * 判断账号是否已存在
     *
     * @param account
     */
    public void checkAgentUserAccountExist(String account) throws ViChatException {
        AgentUser agentUser = getAgentUserByAccount(account);
        if (agentUser != null) {
            String errorMsg = I18NUtil.getMessage("UserServiceImpl.checkIsAccountExist.error_AccountIsExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_accountIsExist, errorMsg);
        }
    }

    @Override
    public Map<String, List<AgentUser>> batchUpdateAgentUser(List<AgentUser> users) {
        Map<String, List<AgentUser>> rtnMap = new HashMap<String, List<AgentUser>>();
        List<AgentUser> successList = new ArrayList<AgentUser>();
        List<AgentUser> failList = new ArrayList<AgentUser>();

        for (AgentUser user : users) {
            try {
                this.saveAgentUser(user);
                successList.add(user);
            } catch (Exception e) {
                logger.error("batchUpdateUser", e);
                e.printStackTrace();
                failList.add(user);
            }
        }
        rtnMap.put("SUCCESS_LIST", successList);
        rtnMap.put("FAIL_LIST", failList);
        return rtnMap;
    }

    public void updateAgentExpiredDate(AgentUser sessionUser, AgentCompany agentCompanyIn, Integer monthNumber, String remark) throws ViChatException {
        AgentCompany agentCompanyOut = this.getAgentCompanyByAgentId(sessionUser.getAgentId());
        if (agentCompanyOut == null) {
            String errorMsg = I18NUtil.getMessage("error_agentCompanyNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_agentCompanyNotExist, errorMsg);
        }
        this.rechargeRecordAgentIn(sessionUser, agentCompanyOut, agentCompanyIn, monthNumber, remark);
        this.rechargeRecordAgentOut(sessionUser, agentCompanyOut, agentCompanyIn, monthNumber, remark);

        //修改出账企业余额
        agentCompanyOut.setAuthMonth(agentCompanyOut.getAuthMonth() - monthNumber);
        agentCompanyDao.update(agentCompanyOut);
        RedisHelper.setAgentCompany(agentCompanyOut.getAgentId(), JSONObject.toJSONString(agentCompanyOut));

        //修改进账企业余额
        agentCompanyIn.setAuthMonth(agentCompanyIn.getAuthMonth() + monthNumber);
        agentCompanyDao.update(agentCompanyIn);
        RedisHelper.setAgentCompany(agentCompanyIn.getAgentId(), JSONObject.toJSONString(agentCompanyIn));
    }

    private void rechargeRecordAgentIn(AgentUser sessionUser, AgentCompany agentCompanyOut, AgentCompany agentCompanyIn, Integer monthNumber, String remark) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj1PartyId(agentCompanyIn.getAgentId());
        rechargeRecord.setObj1PartyName(agentCompanyIn.getCompanyName());
        rechargeRecord.setObj1Type(2L);
        rechargeRecord.setObj1Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setObj2PartyId(agentCompanyOut.getAgentId());
        rechargeRecord.setObj2PartyName(agentCompanyOut.getCompanyName());
        rechargeRecord.setObj2Type(2L);
        rechargeRecord.setBusiType(2L);
        rechargeRecord.setChgBefore(String.valueOf(agentCompanyIn.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(agentCompanyIn.getAuthMonth() + monthNumber));
        rechargeRecord.setChgValue((long) monthNumber);
        rechargeRecord.setChgType(1L);
        rechargeRecord.setRemark(remark);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    private void rechargeRecordAgentOut(AgentUser sessionUser, AgentCompany agentCompanyOut, AgentCompany agentCompanyIn, Integer monthNumber, String remark) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj2PartyId(agentCompanyIn.getAgentId());
        rechargeRecord.setObj2PartyName(agentCompanyIn.getCompanyName());
        rechargeRecord.setObj2Type(2L);
        rechargeRecord.setObj1PartyId(agentCompanyOut.getAgentId());
        rechargeRecord.setObj1PartyName(agentCompanyOut.getCompanyName());
        rechargeRecord.setObj1Type(2L);
        rechargeRecord.setObj1Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(2L);
        rechargeRecord.setChgBefore(String.valueOf(agentCompanyOut.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(agentCompanyOut.getAuthMonth() - monthNumber));
        rechargeRecord.setChgValue((long) (0 - monthNumber));
        rechargeRecord.setChgType(2L);
        rechargeRecord.setRemark(remark);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    public void updateCompanyExpiredDate(AgentUser sessionUser, UserPartyCompany companyIn, Integer monthNumber, String remark) throws ViChatException {
        AgentCompany agentCompanyOut = this.getAgentCompanyByAgentId(sessionUser.getAgentId());
        if (agentCompanyOut == null) {
            String errorMsg = I18NUtil.getMessage("error_agentCompanyNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_agentCompanyNotExist, errorMsg);
        }
        this.rechargeRecordCompanyIn(sessionUser, agentCompanyOut, companyIn, monthNumber, remark);
        this.rechargeRecordCompanyOut(sessionUser, agentCompanyOut, companyIn, monthNumber, remark);

        //修改出账企业余额
        agentCompanyOut.setAuthMonth(agentCompanyOut.getAuthMonth() - monthNumber);
        agentCompanyDao.update(agentCompanyOut);
        RedisHelper.setAgentCompany(agentCompanyOut.getAgentId(), JSONObject.toJSONString(agentCompanyOut));

        //修改进账企业余额
        companyIn.setAuthMonth(companyIn.getAuthMonth() + monthNumber);
        partyCompanyDao.update(companyIn);
        RedisHelper.setPartyCompany(companyIn.getPartyId(), JSONObject.toJSONString(companyIn));
    }

    private void rechargeRecordCompanyIn(AgentUser sessionUser, AgentCompany agentCompanyOut, UserPartyCompany partyCompanyIn, Integer monthNumber, String remark) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj1PartyId(partyCompanyIn.getPartyId());
        rechargeRecord.setObj1PartyName(partyCompanyIn.getCompanyName());
        rechargeRecord.setObj1Type(4L);
        rechargeRecord.setObj1Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setObj2PartyId(agentCompanyOut.getAgentId());
        rechargeRecord.setObj2PartyName(agentCompanyOut.getCompanyName());
        rechargeRecord.setObj2Type(2L);
        rechargeRecord.setBusiType(4L);
        rechargeRecord.setChgBefore(String.valueOf(partyCompanyIn.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(partyCompanyIn.getAuthMonth() + monthNumber));
        rechargeRecord.setChgValue((long) monthNumber);
        rechargeRecord.setChgType(1L);
        rechargeRecord.setRemark(remark);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    private void rechargeRecordCompanyOut(AgentUser sessionUser, AgentCompany agentCompanyOut, UserPartyCompany partyCompanyIn, Integer monthNumber, String remark) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj2PartyId(partyCompanyIn.getPartyId());
        rechargeRecord.setObj2PartyName(partyCompanyIn.getCompanyName());
        rechargeRecord.setObj2Type(4L);
        rechargeRecord.setObj1PartyId(agentCompanyOut.getAgentId());
        rechargeRecord.setObj1PartyName(agentCompanyOut.getCompanyName());
        rechargeRecord.setObj1Type(2L);
        rechargeRecord.setObj1Uid(sessionUser.getAgentUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(4L);
        rechargeRecord.setChgBefore(String.valueOf(agentCompanyOut.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(agentCompanyOut.getAuthMonth() - monthNumber));
        rechargeRecord.setChgValue((long) (0 - monthNumber));
        rechargeRecord.setChgType(2L);
        rechargeRecord.setRemark(remark);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    @Override
    public void batchUpdateAgentUser(Long agentUid, Long state) throws ViChatException {
        AgentUser agentUserFDB = this.getAgentUserByUid(agentUid);
        if (agentUserFDB == null) {
            String errorMsg = I18NUtil.getMessage("error_userNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_userNotExist, errorMsg);
        }
        agentUserFDB.setState(state);
        agentUserDao.update(agentUserFDB);
    }

    public AgentUserOnlineVO getUserOnlineView(AgentUser queryBean) throws Exception {
        AgentUser queryAgentUser = new AgentUser();
        queryAgentUser.setAgentId(queryBean.getAgentId());
        long accountNum = this.countAgentUsers(queryAgentUser).longValue();

        AgentCompany queryAgentCompany = new AgentCompany();
        queryAgentCompany.setParentId(queryBean.getAgentId());
        long childAgentNum = this.countAgentCompany(queryAgentUser, queryAgentCompany);

        UserPartyCompany queryUserPartyCompany = new UserPartyCompany();
        queryUserPartyCompany.setAgentId(queryBean.getAgentId());
        queryUserPartyCompany.setFreeType(null);
        long agentCompanyNum = this.countUserCompanyCCS(queryUserPartyCompany, new UserBasic(), false);
        long agentCompanyUserNum = this.conutUserBasicsAgent(queryAgentUser);

        UserCompanyVO queryUserCompanyBean = new UserCompanyVO();
        queryUserCompanyBean.setAgentId(queryBean.getAgentId());
        long expiringUserNum = userService.countExpiringUser(30, queryUserCompanyBean).longValue();
        AgentUserOnlineVO agentUserOnlineVO = new AgentUserOnlineVO();
        agentUserOnlineVO.setAccountNum(accountNum);
        agentUserOnlineVO.setAgentCompanyNum(agentCompanyNum);
        agentUserOnlineVO.setChildAgentNum(childAgentNum);
        agentUserOnlineVO.setExpiringUserNum(expiringUserNum);
        agentUserOnlineVO.setAgentCompanyUserNum(agentCompanyUserNum);
        return agentUserOnlineVO;
    }

    public long conutUserBasicsAgent(AgentUser queryAgentUser) {
        String hql = "select count(a) from UserBasic a ,UserPartyCompany b where a.state = 1 and b.state = 1 and a.partyId = b.partyId and b.agentId = " + queryAgentUser.getAgentId();
        return userDao.count(hql);
    }

    /**
     * 获取组织编号
     *
     * @param company
     * @return
     */
    private String getAgentCode(AgentCompany company) {
        StringBuilder sql = new StringBuilder();
        if (NumberUtils.isNullOrZero(company.getParentId())) {
            sql.append("select LPAD(max(agent_code+1),6,0) ID from ccsdb.agent_company where parent_id=0");
        } else {
            sql.append("select concat(MIN(t.agent_code),substr(concat('00',substr(MAX(t.agent_code),length(MIN(t.agent_code))+1,3)+1),length(concat('00',substr(MAX(t.agent_code),length(MIN(t.agent_code))+1,3)+1))-2,3)) ID from ccsdb.agent_company t where t.agent_code like '").append(company.getAgentCode() + "%'");
        }
        String orgCode = (String) agentCompanyDao.executeQueryBasic(sql.toString(), "ID", StringType.INSTANCE);
        if (StringUtils.isBlank(orgCode)) {
            orgCode = "000001";
        }
        return orgCode;
    }

    public List<AgentUseVO> queryAgentCompanyShort(String name, Long agentId, Long parentId, PageFilter pageFilter) throws ViChatException {
        HashMap params = new HashMap<>();
        String hql = "select agent_id as agentId,company_name as companyName from ccsdb.agent_company where state = 1";
        if (StringUtils.isNotBlank(name)) {
            hql += " and company_name like :companyName";
            params.put("companyName", "%" + name + "%");
        }
        if (parentId != null) {
            hql += " and parent_id = :parentId";
            params.put("parentId", parentId);
        }
        return agentCompanyDao.findVoBySql(hql, params, AgentUseVO.class, pageFilter.getPage(), pageFilter.getRows());
    }

    public List<UserPartyCompany> queryUserPartyCompanyShort(String name, long agentId, PageFilter pageFilter) throws ViChatException {
        HashMap params = new HashMap<>();
        String hql = "select partyId,companyName from UserPartyCompany where state = 1 and agentId = :agentId";
        params.put("agentId", agentId);
        if (StringUtils.isNotBlank(name)) {
            hql += " and companyName like :companyName";
            params.put("companyName", "%" + name + "%");
        }
        return partyCompanyDao.find(hql, params, pageFilter.getPage(), pageFilter.getRows());
    }

    public List<UserBasic> queryUserBasicShort(String name, long partyId, PageFilter pageFilter) throws ViChatException {
        HashMap params = new HashMap<>();
        String hql = "select uid,userName from UserBasic where state = 1 and partyId = :partyId ";
        params.put("partyId", partyId);
        if (StringUtils.isNotBlank(name)) {
            hql += " and userName like :userName";
            params.put("userName", "%" + name + "%");
        }
        return userDao.find(hql, params, pageFilter.getPage(), pageFilter.getRows());
    }

    public List<RechargeRecord> queryRechargeRecord(RechargeRecord queryBean, boolean isPrecise, PageFilter pageFilter) throws Exception {
        String hql = "from RechargeRecord where 1=1";
        HashMap params = new HashMap();
        return rechargeRecordDao.find(hql + rechargeRecordWhereHql(queryBean, params, isPrecise) + " order by rcdId desc ", params, pageFilter.getPage(), pageFilter.getRows());
    }

    public long countRechargeRecord(RechargeRecord queryBean, boolean isPrecise) throws Exception {
        String hql = "select count(*) from RechargeRecord where 1=1";
        HashMap params = new HashMap();
        return rechargeRecordDao.count(hql + rechargeRecordWhereHql(queryBean, params, isPrecise), params);
    }


    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String rechargeRecordWhereHql(RechargeRecord bean, Map<String, Object> params, boolean isPrecise) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getObj1PartyId())) {
                hql += " and obj1PartyId = :obj1PartyId";
                params.put("obj1PartyId", bean.getObj1PartyId());
            }
            if (StringUtils.isNotBlank(bean.getObj1PartyName())) {
                hql += " and obj1PartyName like :obj1PartyName";
                params.put("obj1PartyName", "%" + URLDecoder.decode(bean.getObj1PartyName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj2PartyId())) {
                hql += " and obj2PartyId = :obj2PartyId";
                params.put("obj2PartyId", bean.getObj2PartyId());
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj2Uid())) {
                hql += " and obj2Uid = :obj2Uid";
                params.put("obj2Uid", bean.getObj2Uid());
            }
            if (StringUtils.isNotBlank(bean.getObj2Uname())) {
                hql += " and obj2Uname like :obj2Uname";
                params.put("obj2Uname", "%" + URLDecoder.decode(bean.getObj2Uname(), "UTF-8") + "%");
            }
            if (StringUtils.isNotBlank(bean.getObj2PartyName())) {
                hql += " and obj2PartyName like :obj2PartyName";
                params.put("obj2PartyName", "%" + URLDecoder.decode(bean.getObj2PartyName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj1Type())) {
                hql += " and obj1Type = :obj1Type";
                params.put("obj1Type", bean.getObj1Type());
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj1Uid())) {
                hql += " and obj1Uid = :obj1Uid";
                params.put("obj1Uid", bean.getObj1Uid());
            }
            if (StringUtils.isNotBlank(bean.getObj1Uname())) {
                hql += " and obj1Uname like :obj1Uname";
                params.put("obj1Uname", "%" + URLDecoder.decode(bean.getObj1Uname(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj2Type())) {
                hql += " and obj2Type = :obj2Type";
                params.put("obj2Type", bean.getObj2Type());
            }
            if (NumberUtils.isNotNullOrZero(bean.getChgType())) {
                hql += " and chgType = :chgType";
                params.put("chgType", bean.getChgType());
            }
            if (bean.getStartDate() != null) {
                hql += " and createTime >= :startDate";
                params.put("startDate", bean.getStartDate());
            }
            if (bean.getEndDate() != null) {
                hql += " and createTime <= :endDate";
                params.put("endDate", bean.getEndDate());
            }
            if (NumberUtils.isNotNullOrZero(bean.getBusiType())) {
                hql += " and busiType = :busiType";
                params.put("busiType", bean.getBusiType());
            }


        }
        return hql;
    }

    @Override
    public void setRechargeRecordRemark(long logId, String remark) throws ViChatException {
        RechargeRecord rechargeRecordFDB = this.getRechargeRecordById(logId);
        if (rechargeRecordFDB != null) {
            rechargeRecordFDB.setRemark(remark);
            rechargeRecordDao.update(rechargeRecordFDB);
        } else {
            String errorMsg = I18NUtil.getMessage("error_recordNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_recordNotExist, errorMsg);
        }
    }

    public RechargeRecord getRechargeRecordById(long rcdId) {
        return rechargeRecordDao.get(RechargeRecord.class, rcdId);
    }

    public void assginSN(List<SnResource> snResourceList, Long agentId) {
        for (SnResource snResource : snResourceList) {
            snResource.setAgentId(agentId);
            snResource.setResState(0L);
            this.saveSnResource(snResource);
        }
    }

    public SnResource querySnResourceBySN(String sn) {
        HashMap params = new HashMap<>();
        String hql = "from SnResource where state = 1 and sn = :sn";
        params.put("sn", sn);
        List<SnResource> snResourceList = snResourceDao.find(hql, params);
        if (snResourceList != null && !snResourceList.isEmpty()) {
            return snResourceList.get(0);
        }
        return null;
    }

    public SnResource queryNotAssignSnResourceBySN(String sn, long agentId) {
        HashMap params = new HashMap<>();
        String hql = "from SnResource where state = 1 and resState = 1 and sn = :sn and agentId = :agentId ";
        params.put("sn", sn);
        params.put("agentId", agentId);
        List<SnResource> snResourceList = snResourceDao.find(hql, params);
        if (snResourceList != null && !snResourceList.isEmpty()) {
            return snResourceList.get(0);
        }
        return null;
    }

    public SnResource saveSnResource(SnResource snResource) {
        if (NumberUtils.isNullOrZero(snResource.getSnId())) {
            snResourceDao.save(snResource);
        } else {
            snResourceDao.update(snResource);
        }
        return snResource;
    }

    public List<SnResource> querySnResource(SnResource snResource, PageFilter pageFilter) {
        String hql = "from SnResource where state = 1 ";
        HashMap params = new HashMap();
        return snResourceDao.find(hql + snResourceWhereHql(snResource, params), params, pageFilter.getPage(), pageFilter.getRows());
    }

    public long countSnResource(SnResource snResource) {
        String hql = "select count(*) from SnResource where state = 1 ";
        HashMap params = new HashMap();
        return snResourceDao.count(hql + snResourceWhereHql(snResource, params), params);
    }

    private String snResourceWhereHql(SnResource snResource, HashMap params) {
        String hql = "";
        if (NumberUtils.isNotNullOrZero(snResource.getSnId())) {
            hql += " and snId = :snId";
            params.put("snId", snResource.getSnId());
        }
        if (NumberUtils.isNotNullOrZero(snResource.getAgentId())) {
            hql += " and agentId = :agentId";
            params.put("agentId", snResource.getAgentId());
        }
        if (snResource.getResState() != null) {
            hql += " and resState = :resState";
            params.put("resState", snResource.getResState());
        }
        if (StringUtils.isNotBlank(snResource.getSn())) {
            hql += " and sn like :sn";
            params.put("sn", "%" + snResource.getSn() + "%");
        }
        if (StringUtils.isNotBlank(snResource.getSnType())) {
            hql += " and snType like :snType";
            params.put("snType", snResource.getSnType() + "%");
        }
        return hql;
    }

    public void deleteAgent(long agentId) {
        AgentCompany agentCompany = this.getAgentCompanyByAgentId(agentId);
        if (agentCompany != null) {
            agentCompany.setState(0L);
            agentCompanyDao.update(agentCompany);
        }
    }

    public List<RechargeRecord> queryRechargeRecordAgent(RechargeRecord creditRecord, PageFilter pageFilter) throws Exception {
        String hql = "from RechargeRecord where busiType in (1,2,3) ";
        HashMap params = new HashMap();
        return rechargeRecordDao.find(hql + rechargeRecordWhereHql(creditRecord, params, false) + " order by logId desc ", params, pageFilter.getPage(), pageFilter.getRows());
    }

    public long countRechargeRecordAgent(RechargeRecord creditRecord) throws Exception {
        String hql = "select count(*) from RechargeRecord where busiType in (1,2,3) ";
        HashMap params = new HashMap();
        return rechargeRecordDao.count(hql + rechargeRecordWhereHql(creditRecord, params, false), params);
    }

    /**
     * 获取客服用户信息
     *
     * @param uid
     * @return
     */
    public CcsUser getCcsUserInfoById(long uid) {

        String jsonStr = RedisHelper.getCcsUser(uid);
        CcsUser ccsUser = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            ccsUser = JSONObject.parseObject(jsonStr, CcsUser.class);
        } else {
            ccsUser = ccsUserInfoDao.get(CcsUser.class, uid);
            if (ccsUser != null) {
                RedisHelper.setCcsUser(ccsUser.getCcsUid(), JSONObject.toJSONString(ccsUser));
            }
        }
        return ccsUser;
    }

    public void deleteAgentUser(Long agentUid) throws ViChatException {
        AgentUser agentUser = this.getAgentUserByUid(agentUid);
        if (agentUser != null) {
            agentUser.setState(0L);
            agentUserDao.update(agentUser);
        } else {
            String errorMsg = I18NUtil.getMessage("error_userNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_userNotExist, errorMsg);
        }
    }


    public List<UserBasic> queryUserBasicToRecharge(UserBasic bean, PageFilter pf, long agentId) throws Exception {
        String hql = "select a from UserBasic a,UserPartyCompany b where a.state in (1,9) and a.partyId = b.partyId and b.agentId = :agentId";
        HashMap params = new HashMap();
        params.put("agentId", agentId);

        if (NumberUtils.isNotNullOrZero(bean.getUid())) {
            hql += " and uid = :uid";
            params.put("uid", bean.getUid());
        }

        if (StringUtils.isNotBlank(bean.getUserName())) {
            hql += " and a.userName like :userName";
            params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
            hql += " and a.partyId = :partyId";
            params.put("partyId", bean.getPartyId());
        }


        List<UserBasic> users = userDao.find(hql, params, pf.getPage(), pf.getLimit());

        return users;
    }

    public long countUserBasicToRecharge(UserBasic bean, long agentId) throws Exception {
        String hql = "select count(*) from UserBasic a,UserPartyCompany b where a.state in (1,9) and a.partyId = b.partyId and b.agentId = :agentId";
        HashMap params = new HashMap();
        params.put("agentId", agentId);

        if (NumberUtils.isNotNullOrZero(bean.getUid())) {
            hql += " and uid = :uid";
            params.put("uid", bean.getUid());
        }

        if (StringUtils.isNotBlank(bean.getUserName())) {
            hql += " and a.userName like :userName";
            params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
        }
        if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
            hql += " and a.partyId = :partyId";
            params.put("partyId", bean.getPartyId());
        }

        return userDao.count(hql, params);
    }

}
